/**
 * 
 */
package com.imonsoft.common.util;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.imonsoft.common.constant.CCommon;

/**
 * 通过ThreadLocal传递资源
 * 
 * @author LiQianHui
 * @date 2013-04-17
 * @version 2013
 */
public abstract class ContextUtil {

	private final static Log logger = LogFactory.getLog(ContextUtil.class);

	public static HttpServletRequest getHttpServletRequest() {
		HttpServletRequest request = get(CCommon.REQUEST, HttpServletRequest.class);
		if (request == null) {
			// WebContext wc = WebContextFactory.get();
			// if (wc != null) {
			// request = wc.getHttpServletRequest();
			// }
		}
		return request;
	}

	public static HttpServletResponse getHttpServletResponse() {
		HttpServletResponse response = get(CCommon.RESPONSE, HttpServletResponse.class);
		if (response == null) {
			// WebContext wc = WebContextFactory.get();
			// if (wc != null) {
			// request = wc.getHttpServletRequest();
			// }
		}
		return response;
	}

	/**
	 * 此方法只能在Web服务器环境下使用
	 * 
	 * @return
	 */
	public static HttpSession getSession() {
		// WebContext wc = WebContextFactory.get();
		// if (wc != null) {
		// return wc.getSession(false);
		// } else
		{
			HttpServletRequest request = get(CCommon.REQUEST, HttpServletRequest.class);
			if (request != null) {
				return request.getSession(false);
			}
		}
		logger.warn("此方法只能在Web服务器环境下使用.");
		return null;
	}

	/**
	 * 此方法只能在Web服务器环境下使用
	 * 
	 * @return
	 */
	public static ServletContext getServletContext() {
		// WebContext wc = WebContextFactory.get();
		// if (wc != null) {
		// return wc.getServletContext();
		// } else
		{
			ServletContext context = get(CCommon.SERVLET_CONTEXT, ServletContext.class);
			if (context != null) {
				return context;
			}
		}
		logger.warn("此方法只能在Web服务器环境下使用.");
		return null;
	}

	/**
	 * "此方法只能在Web服务器环境下使用
	 * 
	 * @param path
	 * @return 返回绝对路径，以File.separator结尾
	 */
	public static String getRealPath(String path) {
		ServletContext sc = getServletContext();
		if (sc != null) {
			String str = sc.getRealPath(path);
			if (!str.endsWith("/") && !str.endsWith(File.separator)) {
				str += File.separator;
			}
			return str;
		}
		logger.warn("此方法只能在Web服务器环境下使用.");
		return null;
	}

	/**
	 * 用于透明的传递Web层资源到Service层或DAO层
	 */
	private static final ThreadLocal<Map<String, Object>> context = new ContextThreadLocal();

	public static Object get(String attribute) {
		Map<?, ?> map = (Map<?, ?>) context.get();
		return map.get(attribute);
	}

	@SuppressWarnings("unchecked")
	public static <T> T get(String attribute, Class<T> clazz) {
		return (T) get(attribute);
	}

	public static void set(String attribute, Object value) {
		Map<String, Object> map = context.get();
		map.put(attribute, value);
	}

	/**
	 * 参看com.imonsoft.common.filte.OpenContextInTierFilter
	 * 
	 * @param request
	 * @param response
	 * @param servletContext
	 */
	public static void setWebContext(HttpServletRequest requestServletRequest, HttpServletResponse httpServletResponse, ServletContext servletContext) {
		Map<String, Object> map = context.get();
		map.put(CCommon.REQUEST, requestServletRequest);
		map.put(CCommon.RESPONSE, httpServletResponse);
		map.put(CCommon.SERVLET_CONTEXT, servletContext);
	}

	/**
	 * 将message保存到当前session中，在下一次请求前将message移入request()
	 * 
	 * @param message
	 */
	public static void setFlashMessage(String message) {
		HttpSession httpSession = getSession();
		if (httpSession != null) {
			httpSession.setAttribute(CCommon.FLASH_MESSAGE, message);
		}
		HttpServletRequest request = getHttpServletRequest();
		if (request == null) {
			logger.warn("HttpServletRequest is null.");
			return;
		}
		request.setAttribute(CCommon.FLASH_MESSAGE, message);
	}

	/**
	 * 一次请求只能使用一次
	 * 
	 * @return
	 */
	public static String getFlashMessage() {
		HttpServletRequest request = getHttpServletRequest();
		if (request == null) {
			logger.warn("HttpServletRequest is null.");
			return null;
		}
		String message = (String) request.getAttribute(CCommon.FLASH_MESSAGE);
		if (message != null) {
			HttpSession httpSession = getSession();
			if (httpSession != null) {
				httpSession.removeAttribute(CCommon.FLASH_MESSAGE);
			}
		}
		return message;
	}

	public static ApplicationContext getWebApplicationContext() {
		ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
		return ctx;
	}

	public static ApplicationContext getWebApplicationContext(ServletContext context) {
		ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(context);
		return ctx;
	}

	public static <T> T getBean(String name, Class<T> clazz) {
		ApplicationContext ctx = getWebApplicationContext();
		return (T) ctx.getBean(name, clazz);
	}

	public static <T> T getBean(ServletContext context, String name, Class<T> clazz) {
		ApplicationContext ctx = getWebApplicationContext(context);
		return (T) ctx.getBean(name, clazz);
	}

	public static void unset() {
		Map<String, Object> map = context.get();
		map.clear();
	}

	private static class ContextThreadLocal extends ThreadLocal<Map<String, Object>> {
		@Override
		protected Map<String, Object> initialValue() {
			return new HashMap<String, Object>(2);
		}
	}
}
